package com.sky.sky_server.mapper;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;

import com.sky.sky_pojo.dto.OrderOverViewVO;
import com.sky.sky_pojo.dto.OrderStatisticsVO;
import com.sky.sky_pojo.entity.OrderQueryPage;
import com.sky.sky_pojo.entity.Orders;

@Mapper
public interface OrderMapper {

    /**
     * 新增订单,并主键返回
     * @param order
     * @return
     */
    @Insert("insert into orders (" +
        "number, status, user_id, address_book_id, order_time, checkout_time, " +
        "pay_method, amount, remark, phone, address, user_name, consignee, " +
        "cancel_reason, rejection_reason, cancel_time, estimated_delivery_time, " +
        "delivery_status, delivery_time, pack_amount, tableware_number, tableware_status" +
        ") values(" +
        "#{number}, #{status}, #{userId}, #{addressBookId}, #{orderTime}, #{checkoutTime}, " +
        "#{payMethod}, #{amount}, #{remark}, #{phone}, #{address}, #{userName}, #{consignee}, " +
        "#{cancelReason}, #{rejectionReason}, #{cancelTime}, #{estimatedDeliveryTime}, " +
        "#{deliveryStatus}, #{deliveryTime}, #{packAmount}, #{tablewareNumber}, #{tablewareStatus}" +
        ")")
    @Options(useGeneratedKeys = true, keyProperty = "id") // 主键返回
    int insert(Orders order);

    /**
     * 根据根据订单号查询订单
     */
    @Select("select * from orders where number = #{number}")
    Orders selectByNumber(String number);

    /** 
     * 根据id查询订单
     */
    @Select("select * from orders where id = #{id}")
    Orders selectById(Long id);

    /**
     * 根据id更新订单
     * @param orders
     */
    int updateById(Orders orders);

    /**
     * l历史订单分页查询
     * @param orderQueryPage
     * @return
     */
    List<Orders> selectQueryPage(OrderQueryPage orderQueryPage);

    /**
     * 根据状态和创建时间查询订单
     * @param code
     * @param beforeTime
     * @return
     */
    @Select("select * from orders where status = #{code} and order_time < #{beforeTime}")
    List<Orders> selectByStatusAndTime(Integer code, LocalDateTime beforeTime);


    /**
     * 根据开始和结束时间统计每天的营业额
     * @param begin
     * @param end
     * @return
     */
    List<Double> turnoverStatistics(LocalDate startDate, LocalDateTime endDate);

    /**
     * 根据开始和结束时间统计每天的订单数
     * @param begin
     * @param end
     * @return
     */
    List<Integer> orderStatisticsDailyTotal(LocalDate begin, LocalDateTime end);

    /**
     * 根据开始和结束时间统计每天的有效订单数
     * @param begin
     * @param end
     * @return
     */
    List<Integer> orderStatisticsDailyValid(LocalDate begin, LocalDateTime end);

    /**
     * 根据id查询订单包含的菜品
     * @param id
     * @return
     */
    // todo直接查询的冗余字段，在管理修改菜品信息也更新冗余字段之前，这样做都是有问题的，可能会查询到过时的数据
    @Select("select od.name from orders o left join order_detail od on o.id = od.order_id where o.id = #{id}")
    List<String> getOrderContainsDishList(Long id);

    /**
     * 统计各个状态的订单数量，管理端
     * @return
     */
    OrderStatisticsVO statisticsOrder();

    /**
     * 查询订单管理数据
     * @return
     */
    OrderOverViewVO overviewOrders();

}
